/******************************************************************************
 * $Id: prefs.c,v 1.78 2004/09/23 03:24:49 jimb Exp $
 * @file
 * @author  Jim Brooks http://www.jimbrooks.org
 * @brief   Functions to support user editing preferences.
 ******************************************************************************/

#include "common.h"
#include "prefs.h"

#include "main.h"
#include "widgets.h"
#include "text.h"
#include "treefunc.h"
#include "statusbar.h"
#include "font.h"

static GtkWidget*	pWidgetPropertyBox;
static GtkWidget*	pWidgetEntryTabWidth;
static GtkWidget*	pWidgetEntryMaxTags;
static GtkWidget*	pWidgetEntryMouseWheelNormal;
static GtkWidget*	pWidgetEntryMouseWheelFast;
static GtkWidget*	pWidgetRadioToolbarPlacementBelow;
static GtkWidget*	pWidgetRadioToolbarPlacementRight;
static GtkWidget*	pWidgetRadioTextLeft;
static GtkWidget*	pWidgetRadioTextRight;
static GtkWidget*	pWidgetRadioDialogPlacementDefaultWm;
static GtkWidget*	pWidgetRadioDialogPlacementTopCorner;
static GtkWidget*	pWidgetRadioDialogPlacementBottomCorner;
static GtkWidget*	pWidgetRadioDialogPlacementMiddle;
static GtkWidget*	pWidgetRadioDialogPlacementRestore;
static GtkWidget*	pWidgetRadioAuxKeyLeftCtrl;
static GtkWidget*	pWidgetRadioAuxKeyLeftShift;
static GtkWidget*	pWidgetRadioTreeKeyLeftCtrl;
static GtkWidget*	pWidgetRadioTreeKeyLeftShift;
static GtkWidget*	pWidgetRadioTreeKeyLeftAlt;
static GtkWidget*	pWidgetRadioSearchDefaultNormal;
static GtkWidget*	pWidgetRadioSearchDefaultRegex;
static GtkWidget*	pWidgetRadioRegexScopeLine;
static GtkWidget*	pWidgetRadioRegexScopeSpan;

static GtkWidget*	pWidgetCheckLineColumn;
static GtkWidget*	pWidgetCheckConserveMemory;
static GtkWidget*	pWidgetCheckEnableProcessPendingEvents;
static GtkWidget*	pWidgetCheckBuildFuncTree;
static GtkWidget*	pWidgetCheckFuncTreeFontify;
static GtkWidget*	pWidgetCheckFuncTreeVerbose;
static GtkWidget*	pWidgetCheckAutoSelectNotebookPage;
static GtkWidget*	pWidgetCheckKnrStyle;

// for Editor option
static GtkWidget*	pWidgetCheckHilite;
static GtkWidget*   pWidgetCheckCurrentLineHighlight;
static GtkWidget*   pWidgetCheckSpaceInsteadTab;
static GtkWidget*   pWidgetCheckLineNumber;
static GtkWidget*   pWidgetCheckSmartHOME_END;
static GtkWidget*   pWidgetCheckAutoIndent;
static GtkWidget*   pWidgetCheckRightMargin;
/*
static GtkWidget*   pWidgetCheckLeftMargin;
static GtkWidget*   pWidgetCheckWordWrap;
*/

// The List/Tree and Text background's color (GtkColorButton)
static GtkWidget*   pWidgetPropertyPageButtonBgColorListTree;
static GtkWidget*   pWidgetPropertyPageButtonBgColorText;
static GtkWidget*   pWidgetPropertyPageButtonSelBgColor;

static gchar              strPropertyPageButtonColorListTree[]=N_("Select background color for list/tree");
static gchar              strPropertyPageButtonColorText[]  =N_("Select background color for Text");
static gchar              strPropertyPageButtonSelColorText[]  =N_("Select background color for selected item");

static GtkWidget*	pWidgetPropertyPageButtonFontUndo;
static GtkWidget*	pWidgetPropertyPageButtonFontDefault;
static GtkWidget*	pWidgetPropertyPageButtonFontText;
static GtkWidget*	pWidgetPropertyPageButtonFontList;
/*
static GtkWidget*	pWidgetPropertyPageButtonFontTree;
static GtkWidget*	pWidgetPropertyPageButtonFontHiliteComment;
static GtkWidget*	pWidgetPropertyPageButtonFontHiliteKeyword;
static GtkWidget*	pWidgetPropertyPageButtonFontHiliteType;
static GtkWidget*	pWidgetPropertyPageButtonFontHiliteSymbol;
*/
static GtkWidget*	pWidgetPropertyPageButtonFontAll;
static gchar		strPropertyPageButtonFontText[]          = N_("Select font in text");
static gchar		strPropertyPageButtonFontList[]          = N_("Select font in List/Tree widgets");
/*static gchar		strPropertyPageButtonFontTree[]          = "Select base font in tree widgets";
static gchar		strPropertyPageButtonFontHiliteComment[] = "Select font in hilited comments";
static gchar		strPropertyPageButtonFontHiliteKeyword[] = "Select font in hilited keywords";
static gchar		strPropertyPageButtonFontHiliteType[]    = "Select font in hilited types";
static gchar		strPropertyPageButtonFontHiliteSymbol[]  = "Select font in hilited symbols";
*/
static gchar		strPropertyPageButtonFontAll[]           = N_("(Select one font for all of the above)");
static gchar		strPropertyPageButtonFontUndo[]          = N_("(Undo changes)");
static gchar		strPropertyPageButtonFontDefault[]       = N_("(Restore default fonts)");

static gint			toApply_toolbarPlacement;
static gboolean		toApply_textLeft;
static gint			toApply_dialogPlacement;
static gboolean		toApply_hilite;
static gboolean		toApply_showLineColumn;
static gboolean		toApply_conserveMemory;
static gboolean		toApply_enableProcessPendingEvents;
static gboolean		toApply_buildFuncTree;
static gboolean		toApply_fontifyFuncTrees;
static gboolean		toApply_funcTreeVerbose;
static gboolean		toApply_autoSelectNotebookPage;
static gboolean		toApply_knrStyle;
static gint			toApply_searchDefault;
static gint			toApply_regexScope;
static gint			toApply_auxKey			= -1;		/* mutually exclusive */
static gint			toApply_treeKey			= -1;

static char			fontNameAll[MAX_FONT_NAME_LEN];

enum
{
   PROPERTY_PAGE_FONTS		= 0,
   PROPERTY_PAGE_LAYOUT,
   PROPERTY_PAGE_KEYBOARD,
   PROPERTY_PAGE_SEARCH,
   PROPERTY_PAGE_NUMBERS,
   PROPERTY_PAGE_EDITOR,
   PROPERTY_PAGE_MISC
};

enum
{
   CHANGE_AUX_TEXT_KEY,
   CHANGE_TREE_KEY
};

#define PROPERTY_PAGE_CHECK_BUTTON( P_WIDGET, STRING, PADDING, CALLBACK, BUTTON_STATE ) \
   pWidgetHbox = gtk_hbox_new( FALSE, padding_h );	/* create hbox */					\
   P_WIDGET = gtk_check_button_new();				/* create check button */			\
   gtk_box_pack_start( GTK_BOX(pWidgetHbox),		/* pack check button in hbox */		\
                       P_WIDGET,														\
                       FALSE, TRUE, PADDING );											\
   pWidgetLabel = gtk_label_new( _(STRING) );			/* label check button */			\
   gtk_box_pack_start( GTK_BOX(pWidgetHbox),		/* pack label in hbox */			\
                       pWidgetLabel,													\
                       FALSE, TRUE, PADDING );											\
   gtk_box_pack_start( GTK_BOX(pWidgetVbox),		/* pack hbox in vbox */				\
                       pWidgetHbox,														\
                       FALSE, TRUE, PADDING );											\
   gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(P_WIDGET),							\
                                 BUTTON_STATE );	/* before connecting signal! */		\
   gtk_signal_connect( GTK_OBJECT(P_WIDGET),		/* connect toggle signal */			\
                       "toggled",														\
                       GTK_SIGNAL_FUNC(CALLBACK),										\
                       NULL );

/*---------------------------------------------------------------------------*/

/*****************************************************************************
 * Create a property page widget for the user to edit preferences.
 * Called when /Prefs/Edit Prefs is selected.
 *****************************************************************************/
void
EditPrefs( void )
{
   GtkWidget* pWidgetLabel;

  /*
   * Has the property page already been created?
   * If so just give it focus.
   */
   if ( pWidgetPropertyBox )
   {
      gdk_window_raise( GTK_WIDGET(pWidgetPropertyBox)->window );
	  //lv
//	  gtk_window_set_transient_for(GTK_WINDOW(GTK_WIDGET(pWidgetPropertyBox)->window),
//								   GTK_WINDOW(pWidgetMain));
	  //
      return;
   }

  /*
   * Create an empty property page widget.
   */
   pWidgetPropertyBox = gnome_property_box_new();

#if 0
/* doesn't work */
   gtk_widget_hide( GNOME_PROPERTY_BOX(pWidgetPropertyBox)->help_button );
#endif
   gtk_window_set_title( GTK_WINDOW(pWidgetPropertyBox),
                         _("Edit Preferences") );

  /*
   * Connect to Ok button signal.
   */
   gnome_dialog_button_connect(GNOME_DIALOG(pWidgetPropertyBox),
                       3, // button index
                       GTK_SIGNAL_FUNC(HandlerPropertyPageClicked),
                       NULL);
  /*
   * Connect to Apply/Close signals.
   */

   gtk_signal_connect( GTK_OBJECT(pWidgetPropertyBox),
                       "apply",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageApply),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetPropertyBox),
                       "close",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageClose),
                       NULL );

  /*
   * Add font page.
   */
   pWidgetLabel = gtk_label_new( _("Fonts") );
   gnome_property_box_append_page( GNOME_PROPERTY_BOX(pWidgetPropertyBox),
                                   CreatePropertyPageFont(),
                                   pWidgetLabel );

  /*
   * Add layout page.
   */
   pWidgetLabel = gtk_label_new( _("Layout") );
   gnome_property_box_append_page( GNOME_PROPERTY_BOX(pWidgetPropertyBox),
                                   CreatePropertyPageLayout(),
                                   pWidgetLabel );

  /*
   * Add keyboard page.
   */
   pWidgetLabel = gtk_label_new( _("Keyboard") );
   gnome_property_box_append_page( GNOME_PROPERTY_BOX(pWidgetPropertyBox),
                                   CreatePropertyPageKeyboard(),
                                   pWidgetLabel );

  /*
   * Add search page.
   */
   pWidgetLabel = gtk_label_new( _("Search") );
   gnome_property_box_append_page( GNOME_PROPERTY_BOX(pWidgetPropertyBox),
                                   CreatePropertyPageSearch(),
                                   pWidgetLabel );

  /*
   * Add numbers page.
   */
   pWidgetLabel = gtk_label_new(_( "Numbers") );
   gnome_property_box_append_page( GNOME_PROPERTY_BOX(pWidgetPropertyBox),
                                   CreatePropertyPageNumbers(),
                                   pWidgetLabel );

  /*
   * Add Editor page.
   */
   pWidgetLabel = gtk_label_new(_( "Editor") );
   gnome_property_box_append_page( GNOME_PROPERTY_BOX(pWidgetPropertyBox),
                                   CreatePropertyPageEditor(),
                                   pWidgetLabel );
  /*
   * Add misc page.
   */
   pWidgetLabel = gtk_label_new(_( "Misc" ));
   gnome_property_box_append_page( GNOME_PROPERTY_BOX(pWidgetPropertyBox),
                                   CreatePropertyPageMisc(),
                                   pWidgetLabel );

  /*
   * Position/show.
   */
   PositionWidgetAtTopMiddle( pWidgetPropertyBox );
   gtk_widget_show_all( pWidgetPropertyBox );

   return;
}

#define ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFont_X, pWidgetPropertyPageButtonFont_X ) \
{ \
   pWidgetPropertyPageButtonFont_X = gtk_button_new_with_label( _(strPropertyPageButtonFont_X )); \
   gtk_container_add( GTK_CONTAINER(pWidgetButtonBox), \
                      pWidgetPropertyPageButtonFont_X ); \
   gtk_signal_connect( GTK_OBJECT(pWidgetPropertyPageButtonFont_X), \
                       "clicked", \
                       GTK_SIGNAL_FUNC(HandlerPropertyPageFontButton), \
                       _(strPropertyPageButtonFont_X )); \
}

/*****************************************************************************
 * For a font property page, create a widget to be contained by the property page.
 * The font property page will be given buttons to trigger font dialogs.
 * // with color buttons
 *****************************************************************************/
GtkWidget*
CreatePropertyPageFont( void )
{
   GtkTooltips * pTooltips;
   GtkWidget*	pWidgetButtonBox;

  /*
   * Save font names in case user selects Undo.
   */
   SaveFontNames();

  /*
   * Create a vertical button box.
   */
   pWidgetButtonBox = gtk_vbutton_box_new();
   gtk_container_set_border_width( GTK_CONTAINER(pWidgetButtonBox), 8 );

  /*
   * Add button to trigger font dialog to select font in LIST/TREE widget.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontList,
                                  pWidgetPropertyPageButtonFontList );
#if 0
  /*
   * Add button to trigger font dialog to select font in TREE widgets.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontTree,
                                  pWidgetPropertyPageButtonFontTree );
#endif
  /*
   * Add button to trigger font dialog to select font in TEXT widget.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontText,
                                  pWidgetPropertyPageButtonFontText );
#if 0
  /*
   * Add button to trigger font dialog to select font in HILITED COMMENTS.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontHiliteComment,
                                  pWidgetPropertyPageButtonFontHiliteComment );

  /*
   * Add button to trigger font dialog to select font in HILITED KEYWORDS.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontHiliteKeyword,
                                  pWidgetPropertyPageButtonFontHiliteKeyword );

  /*
   * Add button to trigger font dialog to select font in HILITED TYPES.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontHiliteType,
                                  pWidgetPropertyPageButtonFontHiliteType );

  /*
   * Add button to trigger font dialog to select font in HILITED SYMBOLS.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontHiliteSymbol,
                                  pWidgetPropertyPageButtonFontHiliteSymbol );

  /*
   * Add button to trigger font dialog to select all fonts.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontAll,
                                  pWidgetPropertyPageButtonFontAll );
#endif

   // add a ColorButton for Text Background
   pWidgetPropertyPageButtonBgColorText=gtk_color_button_new_with_color(
                              &colorTextWidgetTextBg);
   gtk_color_button_set_title(GTK_COLOR_BUTTON(pWidgetPropertyPageButtonBgColorText),
                                                   _(strPropertyPageButtonColorText));
   gtk_container_add(GTK_CONTAINER(pWidgetButtonBox),
                        pWidgetPropertyPageButtonBgColorText);
   g_signal_connect(G_OBJECT(pWidgetPropertyPageButtonBgColorText),
                                "color-set",
                                G_CALLBACK(cb_set_bg_color),
                                "setTextViewBgColor"); // don't translate it!!
   pTooltips=gtk_tooltips_new();
   gtk_tooltips_set_tip(pTooltips,
                        pWidgetPropertyPageButtonBgColorText,
                        _(strPropertyPageButtonColorText),
                        NULL);

   // add a Color Button for List/Tree Background
   pWidgetPropertyPageButtonBgColorListTree=gtk_color_button_new_with_color(
                              &colorClistWidgetTextBg);
   gtk_color_button_set_title(GTK_COLOR_BUTTON(pWidgetPropertyPageButtonBgColorListTree),
                                                   _(strPropertyPageButtonColorListTree));
   gtk_container_add(GTK_CONTAINER(pWidgetButtonBox),
                              pWidgetPropertyPageButtonBgColorListTree);
   g_signal_connect(G_OBJECT(pWidgetPropertyPageButtonBgColorListTree),
                                "color-set",
                                G_CALLBACK(cb_set_bg_color),
                                "setListTreeBgColor"); // don't translate it!!
   pTooltips=gtk_tooltips_new();
   gtk_tooltips_set_tip(pTooltips,
                        pWidgetPropertyPageButtonBgColorListTree,
                        _(strPropertyPageButtonColorListTree),
                        NULL);

   // add a Color Button for List/Tree Background
   pWidgetPropertyPageButtonSelBgColor=gtk_color_button_new_with_color(
                              &colorClistWidgetSelBg);
   gtk_color_button_set_title(GTK_COLOR_BUTTON(pWidgetPropertyPageButtonSelBgColor),
                                                   _(strPropertyPageButtonSelColorText));
   gtk_container_add(GTK_CONTAINER(pWidgetButtonBox),
                              pWidgetPropertyPageButtonSelBgColor);
   g_signal_connect(G_OBJECT(pWidgetPropertyPageButtonSelBgColor),
                                "color-set",
                                G_CALLBACK(cb_set_bg_color),
                                "setListTreeSelectedColor"); // don't translate it!!   
   pTooltips=gtk_tooltips_new();
   gtk_tooltips_set_tip(pTooltips,
                        pWidgetPropertyPageButtonSelBgColor,
                        _(strPropertyPageButtonSelColorText),
                        NULL);


  /*
   * Add button to restore default fonts.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontDefault,
                                  pWidgetPropertyPageButtonFontDefault );

  /*
   * Add button to undo font changes.
   */
   ADD_PROPERTY_PAGE_FONT_BUTTON( strPropertyPageButtonFontUndo,
                                  pWidgetPropertyPageButtonFontUndo );
   gtk_widget_set_sensitive( pWidgetPropertyPageButtonFontUndo, FALSE );	/* no undo needed yet */

  /*
   * Done adding each button.
   */
   gtk_container_add( GTK_CONTAINER(pWidgetButtonBox),
                      gtk_label_new( _("Font selections will take effect immediately." ) ));

  /*
   * Return button box.
   */
   return pWidgetButtonBox;
}

#define CREATE_RADIO_BUTTON( FIRST_BUTTON, P_WIDGET, LABEL_STR, PADDING )			\
   P_WIDGET =																		\
   gtk_radio_button_new_with_label( FIRST_BUTTON, /* pass NULL if this is first */	\
                                    _(LABEL_STR) );									\
   gtk_box_pack_start( GTK_BOX(pWidgetVbox),										\
                       P_WIDGET,													\
                       FALSE, TRUE, PADDING );

/*****************************************************************************
 * Create a property page for layout.
 *****************************************************************************/
GtkWidget*
CreatePropertyPageLayout( void )
{
   GtkWidget*	pWidgetVboxOuter;
   const int	padding_v			= 4;
#if 0
   const int	padding_h			= 4;
#endif
   const int	padding_v_radio		= 0;

   GtkWidget*	pWidgetFrame;				/* these are reused */
   GtkWidget*	pWidgetVbox;
#if 0
   GtkWidget*	pWidgetHbox;
   GtkWidget*	pWidgetLabel;
#endif

  /*
   * Create the page's outermost vertical box.
   */
   pWidgetVboxOuter = gtk_vbox_new( FALSE, 8/*padding_v*/ );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Radio buttons for toolbar layout.                                         */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   toApply_toolbarPlacement = toolbarPlacement;

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );

   CREATE_RADIO_BUTTON( NULL,
                        pWidgetRadioToolbarPlacementBelow,
                        N_("below menubar (to narrow main window)"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioToolbarPlacementBelow)),
                        pWidgetRadioToolbarPlacementRight,
                        N_("near right of menubar"),
                        padding_v_radio );

  /*
   * Frame radio buttons.
   */
   pWidgetFrame = gtk_frame_new( _("Placement of toolbar (effective next time program starts)") );
   gtk_container_add( GTK_CONTAINER(pWidgetFrame), pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /*
   * Depress the appropriate radio button (first one is depressed by default).
   */
   if ( toolbarPlacement == TOOLBAR_PLACEMENT_RIGHT )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioToolbarPlacementRight), TRUE );

  /*
   * Connect to toggle signal only for first radio button.
   */
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioToolbarPlacementBelow),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Radio buttons for text widget placement                                   */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   toApply_textLeft = textLeft;

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );

   CREATE_RADIO_BUTTON( NULL,
                        pWidgetRadioTextLeft,
                        N_("place at left side"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioTextLeft)),
                        pWidgetRadioTextRight,
                        N_("place at right side"),
                        padding_v_radio );

  /*
   * Frame radio buttions.
   */
   pWidgetFrame = gtk_frame_new( _("Placement of text widgets (effective next time program starts)") );
   gtk_container_add( GTK_CONTAINER(pWidgetFrame), pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /*
   * Depress the appropriate radio button.
   */
   if ( ! textLeft )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioTextRight), TRUE );

  /*
   * Connect to toggle signal only for left placement (not right).
   */
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioTextLeft),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Radio buttons for dialog widget placement                                 */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   toApply_dialogPlacement = dialogPlacement;

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );

   CREATE_RADIO_BUTTON( NULL,
                        pWidgetRadioDialogPlacementDefaultWm,
                        N_("let window manager place   (default)"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioDialogPlacementDefaultWm)),
                        pWidgetRadioDialogPlacementTopCorner,
                        N_("place near a top corner"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioDialogPlacementDefaultWm)),
                        pWidgetRadioDialogPlacementBottomCorner,
                        N_("place near a bottom corner"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioDialogPlacementDefaultWm)),
                        pWidgetRadioDialogPlacementMiddle,
                        N_("place near middle"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioDialogPlacementDefaultWm)),
                        pWidgetRadioDialogPlacementRestore,
                        N_("try to restore previous placement   (doesn't work perfectly)"),
                        padding_v_radio );

  /*
   * Frame radio buttions.
   */
   pWidgetFrame = gtk_frame_new( _("Placement of dialog widgets") );
   gtk_container_add( GTK_CONTAINER(pWidgetFrame), pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /*
   * Depress the appropriate radio button.
   */
   if      ( dialogPlacement == DIALOG_PLACEMENT_DEFAULT_WM )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioDialogPlacementDefaultWm), TRUE );
   else if ( dialogPlacement == DIALOG_PLACEMENT_TOP_CORNER )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioDialogPlacementTopCorner), TRUE );
   else if ( dialogPlacement == DIALOG_PLACEMENT_BOTTOM_CORNER )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioDialogPlacementBottomCorner), TRUE );
   else if ( dialogPlacement == DIALOG_PLACEMENT_MIDDLE )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioDialogPlacementMiddle), TRUE );
   else if ( dialogPlacement == DIALOG_PLACEMENT_RESTORE )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioDialogPlacementRestore), TRUE );
   else
      WarningMalfunction();

  /*
   * Connect to toggle signals.
   */
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioDialogPlacementDefaultWm),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioDialogPlacementTopCorner),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioDialogPlacementBottomCorner),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioDialogPlacementMiddle),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioDialogPlacementRestore),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   return pWidgetVboxOuter;
}

#define ADD_PROPERTY_PAGE_NUMBER_ENTRY( LABEL_STR, P_WIDGET_ENTRY, NUM_STR )            \
   pWidgetHbox = gtk_hbox_new( FALSE, padding_h );		/* create hbox */				\
   P_WIDGET_ENTRY = gtk_entry_new();					/* create entry */				\
   gtk_entry_set_text( GTK_ENTRY(P_WIDGET_ENTRY), _(NUM_STR) );							\
   gtk_box_pack_start( GTK_BOX(pWidgetHbox),			/* pack entry in hbox */		\
                       P_WIDGET_ENTRY,													\
                       FALSE, TRUE, padding_h );										\
   pWidgetLabel = gtk_label_new( _(LABEL_STR) );			/* create label */				\
   gtk_signal_connect( GTK_OBJECT(P_WIDGET_ENTRY),		/* signal when entry is changed */ \
                       "changed",														\
                       GTK_SIGNAL_FUNC(HandlerPropertyPageEntryModified),				\
                       NULL );															\
   gtk_box_pack_start( GTK_BOX(pWidgetHbox),			/* pack label in hbox */		\
                       pWidgetLabel,													\
                       FALSE, TRUE, padding_h );										\
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),		/* pack hbox into outer vbox */	\
                       pWidgetHbox,														\
                       FALSE, TRUE, padding_v );


/*****************************************************************************
 * Create a property page for entering various numbers.
 *****************************************************************************/
GtkWidget*
CreatePropertyPageNumbers( void )
{
   GtkWidget*	pWidgetVboxOuter;
   const int	padding_h			= 16;
   const int	padding_v			= 4;
   gchar		str[MAX_STRING_LEN];

   GtkWidget*	pWidgetHbox;					/* these are reused */
   GtkWidget*	pWidgetLabel;

  /*
   * Create a vertical box.
   */
   pWidgetVboxOuter = gtk_vbox_new( FALSE, padding_v );

  /*
   * Create entry box for tab width.
   */
   sprintf( str, "%d", tabWidth );
   ADD_PROPERTY_PAGE_NUMBER_ENTRY( N_("tab width (0 selects GTK+ default)"),
                                   pWidgetEntryTabWidth,
                                   str );

  /*
   * Create entry box for max tags.
   */
   sprintf( str, "%d", maxTags );
   ADD_PROPERTY_PAGE_NUMBER_ENTRY( N_("maximum amount of tags to process"),
                                   pWidgetEntryMaxTags,
                                   str );
#if 0 // 此功能很有用,但当前不实现
  /*
   * Create entry box for mouse wheel (affects speed of scrolling).
   */
   sprintf( str, "%.3f", mouseWheelNormal );
   ADD_PROPERTY_PAGE_NUMBER_ENTRY( N_("mouse wheel speed"),
                                   pWidgetEntryMouseWheelNormal,
                                   str );
   sprintf( str, "%.3f", mouseWheelFast );
   ADD_PROPERTY_PAGE_NUMBER_ENTRY( N_("mouse wheel speed (") MOUSE_WHEEL_KEY_STR ")",
                                   pWidgetEntryMouseWheelFast,
                                   str );
#endif
  /*
   * Return box.
   */
   return pWidgetVboxOuter;
}

/*****************************************************************************
 * Create a property page for Editor.
 *****************************************************************************/
GtkWidget*
CreatePropertyPageEditor(void)
{
   GtkWidget*	pWidgetVboxOuter;
   const int	padding_v			= 4;
   const int	padding_h			= 4;

   GtkWidget*	pWidgetFrame;				/* these are reused */
   GtkWidget*	pWidgetVbox;
   GtkWidget*	pWidgetHbox;
   GtkWidget*	pWidgetLabel;

  /*
   * Create the page's outermost vertical box.
   */
   pWidgetVboxOuter = gtk_vbox_new( FALSE, 8/*padding_v*/ );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Editor settings.                                                            */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );
   pWidgetFrame = gtk_frame_new( _("Editor settings") );

   toApply_hilite = hilite;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckHilite,
                               N_("highlight source code"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_hilite );
   
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckCurrentLineHighlight,
                               N_("highlight current line"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_source_view_get_highlight_current_line(
                                      GTK_SOURCE_VIEW(pWidgetTextMain)));
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckSpaceInsteadTab,
                               N_("insert spaces instead of tabs"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_source_view_get_insert_spaces_instead_of_tabs(
                                       GTK_SOURCE_VIEW(pWidgetTextMain)));
   
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckLineNumber,
                               N_("show line number"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_source_view_get_show_line_numbers(
                                       GTK_SOURCE_VIEW(pWidgetTextMain)));
   
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckSmartHOME_END,
                               N_("smart HOME/END"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_source_view_get_smart_home_end(
                                       GTK_SOURCE_VIEW(pWidgetTextMain)));
   
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckAutoIndent,
                               N_("auto indent"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_source_view_get_auto_indent(
                                       GTK_SOURCE_VIEW(pWidgetTextMain)));
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckRightMargin,
                               N_("show right margin"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_source_view_get_show_right_margin(
                                       GTK_SOURCE_VIEW(pWidgetTextMain)));
/*   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckLeftMargin,
                               N_("show left margin"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_text_view_get_left_margin(
                                       GTK_TEXT_VIEW(pWidgetTextMain)));
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckWordWrap,
                               N_("word wrap mode"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               gtk_text_view_get_wrap_mode(
                                       GTK_text_VIEW(pWidgetTextMain)));

 */
   gtk_container_add( GTK_CONTAINER(pWidgetFrame),	/* pack tmp vbox in frame */
                      pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),	/* pack frame in outer vbox*/
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   return pWidgetVboxOuter;

}//PageEditor

/*****************************************************************************
 * Create a property page for misc.
 *****************************************************************************/
GtkWidget*
CreatePropertyPageMisc( void )
{
   GtkWidget*	pWidgetVboxOuter;
   const int	padding_v			= 4;
   const int	padding_h			= 4;

   GtkWidget*	pWidgetFrame;				/* these are reused */
   GtkWidget*	pWidgetVbox;
   GtkWidget*	pWidgetHbox;
   GtkWidget*	pWidgetLabel;

  /*
   * Create the page's outermost vertical box.
   */
   pWidgetVboxOuter = gtk_vbox_new( FALSE, 8/*padding_v*/ );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Misc settings.                                                            */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );
   pWidgetFrame = gtk_frame_new( _("Misc settings") );


   toApply_showLineColumn = showLineColumn;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckLineColumn,
                               N_("enable line column in tags list"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_showLineColumn );

   toApply_autoSelectNotebookPage = autoSelectNotebookPage;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckAutoSelectNotebookPage,
                               N_("automatically select notebook page in response to user actions"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_autoSelectNotebookPage );

   toApply_conserveMemory = conserveMemory;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckConserveMemory,
                               N_("conserve memory (speed tradeoff)"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_conserveMemory );

   toApply_enableProcessPendingEvents = enableProcessPendingEvents;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckEnableProcessPendingEvents,
                               N_("process GTK+ events while busy (more responsive)"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_enableProcessPendingEvents );

   toApply_buildFuncTree = ! skipFuncTree_pref;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckBuildFuncTree,
                               N_("build function tree at startup (disable for speed)"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_buildFuncTree );

   toApply_fontifyFuncTrees = fontifyFuncTrees;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckFuncTreeFontify,
                               N_("display bold/italic fonts in trees (if available)"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_fontifyFuncTrees );

   toApply_funcTreeVerbose = funcTreeVerbose;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckFuncTreeVerbose,
                               N_("verbose function tree"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_funcTreeVerbose );

   toApply_knrStyle = knrStyle;
   PROPERTY_PAGE_CHECK_BUTTON( pWidgetCheckKnrStyle,
                               N_("parse K&R style functions (tree view)"),
                               padding_h,
                               HandlerPropertyPageToggle,
                               toApply_knrStyle );

   gtk_container_add( GTK_CONTAINER(pWidgetFrame),	/* pack tmp vbox in frame */
                      pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),	/* pack frame in outer vbox*/
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   return pWidgetVboxOuter;
}

/*****************************************************************************
 * Create a property page for keyboard.
 *****************************************************************************/
GtkWidget*
CreatePropertyPageKeyboard( void )
{
   GtkWidget*	pWidgetVboxOuter;
   const int	padding_v			= 4;
   const int	padding_v_radio		= 0;

   GtkWidget*	pWidgetFrame;				/* these are reused */
   GtkWidget*	pWidgetVbox;

  /*
   * Create the outermost-level vertical box.
   */
   pWidgetVboxOuter = gtk_vbox_new( FALSE, 8/*padding_v*/ );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Radio buttons for keyboard (key for aux text view).                       */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

  /*
   * Initialize with -1 to indicate don't apply.
   */
   toApply_auxKey = -1;

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );

   CREATE_RADIO_BUTTON( NULL,
                        pWidgetRadioAuxKeyLeftCtrl,
                        _("Left-Ctrl"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioAuxKeyLeftCtrl)),
                        pWidgetRadioAuxKeyLeftShift,
                        _("Left-Shift"),
                        padding_v_radio );

  /*
   * Frame radio buttions.
   */
   pWidgetFrame = gtk_frame_new( _("Key to hyperjump in bottom text view" ));
   gtk_container_add( GTK_CONTAINER(pWidgetFrame), pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /*
   * Depress the appropriate radio button.
   */
   if ( auxKeyGdkKeyval == GDK_Control_L )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioAuxKeyLeftCtrl), TRUE );
   else if ( auxKeyGdkKeyval == GDK_Shift_L )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioAuxKeyLeftShift), TRUE );
   else
      WarningMalfunction();

  /*
   * Connect toggle signals for all buttons.
   */
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioAuxKeyLeftCtrl),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioAuxKeyLeftShift),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Radio buttons for keyboard (key to disable tree updates).                 */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */


  /*
   * Initialize with -1 to indicate don't apply.
   */
   toApply_treeKey = -1;

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );

   CREATE_RADIO_BUTTON( NULL,
                        pWidgetRadioTreeKeyLeftCtrl,
                        "Left-Ctrl",
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioTreeKeyLeftCtrl)),
                        pWidgetRadioTreeKeyLeftShift,
                        "Left-Shift",
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioTreeKeyLeftCtrl)),
                        pWidgetRadioTreeKeyLeftAlt,
                        "Left-Alt",
                        padding_v_radio );

  /*
   * Frame radio buttions.
   */
   pWidgetFrame = gtk_frame_new( _("Key to disable tree updates / speed mouse wheel") );
   gtk_container_add( GTK_CONTAINER(pWidgetFrame), pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /*
   * Depress the appropriate radio button.
   */
   if ( treeKeyGdkKeyval == GDK_Control_L )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioTreeKeyLeftCtrl), TRUE );
   else if ( treeKeyGdkKeyval == GDK_Shift_L )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioTreeKeyLeftShift), TRUE );
   else if ( treeKeyGdkKeyval == GDK_Alt_L )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioTreeKeyLeftAlt), TRUE );
   else
      WarningMalfunction();

  /*
   * Connect toggle signals for all buttons.
   */
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioTreeKeyLeftCtrl),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioTreeKeyLeftShift),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioTreeKeyLeftAlt),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   return pWidgetVboxOuter;
}

/*****************************************************************************
 * Create Search property page.
 *****************************************************************************/
GtkWidget*
CreatePropertyPageSearch( void )
{
   GtkWidget*	pWidgetVboxOuter;
   const int	padding_v			= 4;
   const int	padding_v_radio		= 0;

   GtkWidget*	pWidgetFrame;				/* these are reused */
   GtkWidget*	pWidgetVbox;

  /*
   * Create the page's outermost vertical box.
   */
   pWidgetVboxOuter = gtk_vbox_new( FALSE, 8/*padding_v*/ );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Radio buttons for default searching method.                               */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   toApply_searchDefault = searchDefault;

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );

   CREATE_RADIO_BUTTON( NULL,
                        pWidgetRadioSearchDefaultNormal,
                        _("normal"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioSearchDefaultNormal)),
                        pWidgetRadioSearchDefaultRegex,
                        _("regex"),
                        padding_v_radio );

  /*
   * Frame radio buttons.
   */
   pWidgetFrame = gtk_frame_new( _("Default search method" ));
   gtk_container_add( GTK_CONTAINER(pWidgetFrame), pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /*
   * Depress the appropriate radio button (first one is depressed by default).
   */
   if ( searchDefault == SEARCH_REGEX )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioSearchDefaultRegex), TRUE );

  /*
   * Connect to toggle signal only for first radio button.
   */
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioSearchDefaultNormal),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  /* Radio buttons for scope of regex matching.                                */
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   toApply_regexScope = regexScope;

   pWidgetVbox = gtk_vbox_new( FALSE, padding_v );

   CREATE_RADIO_BUTTON( NULL,
                        pWidgetRadioRegexScopeLine,
                        _("limit matching to one line"),
                        padding_v_radio );

   CREATE_RADIO_BUTTON( gtk_radio_button_group(GTK_RADIO_BUTTON(pWidgetRadioRegexScopeLine)),
                        pWidgetRadioRegexScopeSpan,
                        _("allow matching to span lines"),
                        padding_v_radio );

  /*
   * Frame radio buttons.
   */
   pWidgetFrame = gtk_frame_new( _("Scope of regex matching" ));
   gtk_container_add( GTK_CONTAINER(pWidgetFrame), pWidgetVbox );
   gtk_box_pack_start( GTK_BOX(pWidgetVboxOuter),
                       pWidgetFrame,
                       FALSE, TRUE, padding_v );

  /*
   * Depress the appropriate radio button (first one is depressed by default).
   */
   if ( regexScope == REGEX_SCOPE_SPAN )
      gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioRegexScopeSpan), TRUE );

  /*
   * Connect to toggle signal only for first radio button.
   */
   gtk_signal_connect( GTK_OBJECT(pWidgetRadioRegexScopeLine),
                       "toggled",
                       GTK_SIGNAL_FUNC(HandlerPropertyPageToggle),
                       NULL );

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   return pWidgetVboxOuter;
}

/***********************************************************
 * Callback func for ColorButton color-set event
 ***********************************************************/
void
cb_set_bg_color(GtkColorButton *button,
                              gpointer who)
{
    GdkColor color;
    gtk_color_button_get_color(GTK_COLOR_BUTTON(button),
                                &color);
    if ( 0==CompareStrings((gchar*)who, "setTextViewBgColor"))
    {
             colorTextWidgetTextBg = color;
             ChangeStyleColorText(pWidgetTextAux,
                             &colorTextWidgetTextFg,
                             &colorTextWidgetTextBg);
             ChangeStyleColorText(pWidgetTextMain,
                             &colorTextWidgetTextFg,
                             &colorTextWidgetTextBg);
        
     }
    else
    if ( 0==CompareStrings((gchar*)who, "setListTreeBgColor"))
    {
             colorClistWidgetTextBg = color;
             
             ChangeStyleColorText(pWidgetClistTags,
                               &colorClistWidgetTextFg,
                               &colorClistWidgetTextBg);
              
             ChangeStyleColorText(pWidgetClistModules,
                               &colorClistWidgetTextFg,
                               &colorClistWidgetTextBg);
              
             ChangeStyleColorText(pWidgetClistHistory,
                               &colorClistWidgetTextFg,
                               &colorClistWidgetTextBg);
              if ( pWidgetClistFound )
              {
                     ChangeStyleColorText(pWidgetClistFound,
                               &colorClistWidgetTextFg,
                               &colorClistWidgetTextBg);
              }

             ChangeStyleColorTextSel(pWidgetModuleTree,
                              &colorClistWidgetTextFg,
                              &colorClistWidgetTextBg,
                              &colorClistWidgetSelFg,
                              &colorClistWidgetSelBg);

             ChangeStyleColorTextSel(pWidgetFuncTreeRoot,
                               &colorClistWidgetTextFg,
                               &colorClistWidgetTextBg, 
                               &colorClistWidgetSelFg,
                               &colorClistWidgetSelBg);
    }
    // set the List and Tree's Selected 's color
    else if ( 0==CompareStrings((gchar*)who, "setListTreeSelectedColor"))
    {
            colorClistWidgetSelBg = color;
            //colorClistWidgetSelFg = ???
            // List of Tags/Modules/History/Found
             ChangeStyleColorSel(pWidgetClistTags,
                               &colorClistWidgetSelFg,
                               &colorClistWidgetSelBg);
              
             ChangeStyleColorSel(pWidgetClistModules,
                               &colorClistWidgetSelFg,
                               &colorClistWidgetSelBg);
              
             ChangeStyleColorSel(pWidgetClistHistory,
                               &colorClistWidgetSelFg,
                               &colorClistWidgetSelBg);
              if ( pWidgetClistFound )
              {
                     ChangeStyleColorSel(pWidgetClistFound,
                               &colorClistWidgetSelFg,
                               &colorClistWidgetSelBg);
              }

             // Tree's
             ChangeStyleColorTextSel(pWidgetModuleTree,
                              &colorClistWidgetTextFg,
                              &colorClistWidgetTextBg,
                              &colorClistWidgetSelFg,
                              &colorClistWidgetSelBg);

             ChangeStyleColorTextSel(pWidgetFuncTreeRoot,
                               &colorClistWidgetTextFg,
                               &colorClistWidgetTextBg, 
                               &colorClistWidgetSelFg,
                               &colorClistWidgetSelBg);
    }
    else
        g_return_if_fail(0);
} 


/*****************************************************************************
 * Handler for when a font button is clicked in a property page.
 *****************************************************************************/
void
HandlerPropertyPageFontButton( GtkWidget* pWidget,
                               gpointer   pStr )
{

  /*
   * Create a font selection dialog.
   */
   pWidgetFontSel = gtk_font_selection_dialog_new( (const gchar*)pStr );

  /*
   * Re-select the font.
   * Note that font names such as "6x12" won't appear in a GTK+ font dialog.
   */
        /* list font? */
   if ( CompareStrings( _(strPropertyPageButtonFontList), (char*)pStr) == 0 )
      gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)_(fontNameList) );
#if 0 // tree and list use same font
   else /* tree font? */
   if ( CompareStrings( strPropertyPageButtonFontTree, (char*)pStr) == 0 )
   {
#if 0 //lv
      static gchar* weights[] =
      {
         "medium",
         NULL
      };
      static gchar* slants[] =
      {
         "r",
         NULL
      };
      gtk_font_selection_dialog_set_filter( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                            GTK_FONT_FILTER_BASE,
                                            GTK_FONT_ALL, /*GTK_FONT_BITMAP,*/
                                            NULL,	/* foundries */
                                            weights,/* weights */
                                            slants, /* slants */
                                            NULL,	/* setwidths */
                                            NULL,	/* spacings */
                                            NULL );	/* charsets */
#endif
		gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)_(fontNameTree) );
   }
#endif
   else /* text font? */
   if ( CompareStrings( _(strPropertyPageButtonFontText), (char*)pStr) == 0 )
      gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)_(fontNameText) );
#if 0// all use text font
   else /* hilite comment font? */
   if ( CompareStrings( strPropertyPageButtonFontHiliteComment, (char*)pStr) == 0 )
      gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)fontNameHiliteComment );
   else /* hilite keyword font? */
   if ( CompareStrings( strPropertyPageButtonFontHiliteKeyword, (char*)pStr) == 0 )
      gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)fontNameHiliteKeyword );
   else /* hilite type font? */
   if ( CompareStrings( strPropertyPageButtonFontHiliteType,    (char*)pStr) == 0 )
      gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)fontNameHiliteType    );
   else /* hilite symbol font? */
   if ( CompareStrings( strPropertyPageButtonFontHiliteSymbol,  (char*)pStr) == 0 )
      gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)fontNameHiliteSymbol  );
   else /* select a font for all cases? */
   if ( CompareStrings( strPropertyPageButtonFontAll,  (char*)pStr) == 0 )
      gtk_font_selection_dialog_set_font_name( GTK_FONT_SELECTION_DIALOG(pWidgetFontSel),
                                               (const gchar*)fontNameAll );
#endif
   else /* restore default fonts? */
   if ( CompareStrings( _(strPropertyPageButtonFontDefault),  (char*)pStr) == 0 )
   {
     /*
      * The user choose to restore default fonts.
      * Reset/apply font names, return without creating a font dialog.
      */
      gtk_widget_set_sensitive( pWidgetPropertyPageButtonFontUndo,	/* enable Undo button */
                                TRUE );

      InitFontNames();
      ApplyFonts( DO_APPLY_TREE_FONTS );
      return;
   }
   else /* undo font changes? */
   if ( CompareStrings( _(strPropertyPageButtonFontUndo),  (char*)pStr) == 0 )
   {
     /*
      * The user choose to undo font changes.
      * Reset/apply font names, return without creating a font dialog.
      */
      gtk_widget_set_sensitive( pWidgetPropertyPageButtonFontUndo,	/* disable Undo button */
                                FALSE );

      RestoreFontNames();
      ApplyFonts( DO_APPLY_TREE_FONTS );
      return;
   }
   else
      g_return_if_fail(0);

  /*
   * Connect to signals for the OK/Cancel buttons of the font selection dialog.
   */
   gtk_signal_connect( GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(pWidgetFontSel)->ok_button),
                       "clicked",
                       GTK_SIGNAL_FUNC(HandlerFontSelOk),
                       GTK_FONT_SELECTION_DIALOG(pWidgetFontSel) );
   gtk_signal_connect( GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(pWidgetFontSel)->cancel_button),
                       "clicked",
                       GTK_SIGNAL_FUNC(HandlerFontSelCancel),
                       GTK_FONT_SELECTION_DIALOG(pWidgetFontSel) );

  /*
   * Position/show.
   */
   PositionWidgetAtMiddle( pWidgetFontSel );
   gtk_widget_show( pWidgetFontSel );

   return;
}

/*****************************************************************************
 * Handler for when the OK button of a font dialog is clicked.
 * @param   pWidget
 *          The OK button?
 * @param   pWidgetFsd
 * @param   fontName* (GLOBAL/OUT)
 *          Updated appropriately.
 * @remark  当前使用GtkSourceView，不用再单独设关键字颜色。
 *          GtkTree 不能设置字体
 *****************************************************************************/
void
HandlerFontSelOk( GtkWidget*              pWidget,
                  GtkFontSelectionDialog* pWidgetFsd )
{
   gchar* pFontName;

  /*
   * A change was made, enable Undo button.
   */
   gtk_widget_set_sensitive( pWidgetPropertyPageButtonFontUndo, TRUE );

  /*
   * Get name of font that was selected.
   */
   pFontName = gtk_font_selection_dialog_get_font_name(pWidgetFsd);

  /*
   * Quit if font name is empty.
   */
   if ( IsStringEmpty( pFontName ) )
      return;

  /*
   * The fonts of widgets are supposed to be changed.
   * Determine which widgets are affected by the title of the font dialog.
   */
   /* list font? */
   if ( CompareStrings( _(strPropertyPageButtonFontList), GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameList, pFontName );
      strcpy( fontNameTree,pFontName );
      //ApplyFonts( DONT_APPLY_TREE_FONTS );
      ApplyFonts( DO_APPLY_TREE_FONTS ) ;
   }
#if 0 
   /* tree font? */
   else if ( CompareStrings( _(strPropertyPageButtonFontTree), GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameTree, pFontName );
      if ( ApplyFonts( DO_APPLY_TREE_FONTS ) )
         PrintStatusbar( "Italic/bold varieties of this font are unavailable." );
   }
#endif
   /* text font? */
   else if ( CompareStrings( _(strPropertyPageButtonFontText), GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameText, pFontName );
	  // 下边的部分是多余的，因为在ApplyFonts()中已经执行了。
	  /*
      ChangeStyleFont( pWidgetTextMain, pFontName );
      if ( pWidgetTextAux )
         ChangeStyleFont( pWidgetTextAux, pFontName );
	   */
      ApplyFonts( DONT_APPLY_TREE_FONTS );
   }
#if 0
   /* hilite comment font? */
   else if ( CompareStrings( _(strPropertyPageButtonFontHiliteComment), GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameHiliteComment, pFontName );
      ApplyFonts( DONT_APPLY_TREE_FONTS );
   }
   /* hilite keyword font? */
   else if ( CompareStrings( strPropertyPageButtonFontHiliteKeyword, GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameHiliteKeyword, pFontName );
      ApplyFonts( DONT_APPLY_TREE_FONTS );
   }
   /* hilite type font? */
   else if ( CompareStrings( strPropertyPageButtonFontHiliteType   , GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameHiliteType   , pFontName );
      ApplyFonts( DONT_APPLY_TREE_FONTS );
   }
   /* hilite symbol font? */
   else if ( CompareStrings( strPropertyPageButtonFontHiliteSymbol , GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameHiliteSymbol , pFontName );
      ApplyFonts( DONT_APPLY_TREE_FONTS );
   }
   /* select a font for all cases? */
   else if ( CompareStrings( strPropertyPageButtonFontAll , GTK_WINDOW(pWidgetFsd)->title) == 0 )
   {
      strcpy( fontNameAll , pFontName );

      strcpy( fontNameList, pFontName );
      strcpy( fontNameTree, pFontName );
      strcpy( fontNameText, pFontName );
      strcpy( fontNameHiliteComment, pFontName );
      strcpy( fontNameHiliteKeyword, pFontName );
      strcpy( fontNameHiliteType   , pFontName );
      strcpy( fontNameHiliteSymbol , pFontName );

      ApplyFonts( DO_APPLY_TREE_FONTS );
   }
#endif
   /* none of the above, oops */
   else
   {
      g_return_if_fail(0);
   }

  /*
   * Close the font dialog widget.
   */
   gtk_widget_destroy( GTK_WIDGET(pWidgetFsd) );
}

/*****************************************************************************
 * Handler for when the Cancel button of a font dialog is clicked.
 *****************************************************************************/
void
HandlerFontSelCancel( GtkWidget*              pWidget,
                      GtkFontSelectionDialog* pWidgetFsd )
{
  /*
   * Close the font dialog widget.
   */
   gtk_widget_destroy( GTK_WIDGET(pWidgetFsd) );
}

/*****************************************************************************
 * Handler for when an entry widget in a property page is modified by user.
 *****************************************************************************/
void
HandlerPropertyPageEntryModified( GtkWidget* pWidget,
                              gpointer   pUnused )
{
   gnome_property_box_changed( GNOME_PROPERTY_BOX(pWidgetPropertyBox) );
}

/*****************************************************************************
 * Handler for when a toggle/radio/check button is toggled.
 * (Radio and check buttons are derivations of toggle buttons).
 *****************************************************************************/
void
HandlerPropertyPageToggle( GtkWidget* pWidget,
                           gpointer   pUnused )
{
   gboolean pressed = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pWidget) );

  /*
   * Which toggle/radio/check button?
   * The vars "toApply_*" are pending values -- to commit when/if Apply is clicked.
   */
   if ( pWidget == pWidgetRadioTextLeft )
   {
      toApply_textLeft = pressed;
   }
   else if ( pWidget == pWidgetRadioToolbarPlacementBelow )
   {
      toApply_toolbarPlacement = pressed ? TOOLBAR_PLACEMENT_BELOW : TOOLBAR_PLACEMENT_RIGHT;
   }
   else if ( pWidget == pWidgetRadioDialogPlacementDefaultWm )
   {
      if ( pressed ) toApply_dialogPlacement = DIALOG_PLACEMENT_DEFAULT_WM;
   }
   else if ( pWidget == pWidgetRadioDialogPlacementTopCorner )
   {
      if ( pressed ) toApply_dialogPlacement = DIALOG_PLACEMENT_TOP_CORNER;
   }
   else if ( pWidget == pWidgetRadioDialogPlacementBottomCorner )
   {
      if ( pressed ) toApply_dialogPlacement = DIALOG_PLACEMENT_BOTTOM_CORNER;
   }
   else if ( pWidget == pWidgetRadioDialogPlacementMiddle )
   {
      if ( pressed ) toApply_dialogPlacement = DIALOG_PLACEMENT_MIDDLE;
   }
   else if ( pWidget == pWidgetRadioDialogPlacementRestore )
   {
      if ( pressed ) toApply_dialogPlacement = DIALOG_PLACEMENT_RESTORE;
   }
   else if ( pWidget == pWidgetCheckLineColumn )
   {
      toApply_showLineColumn  = pressed;
   }
   else if ( pWidget == pWidgetCheckConserveMemory )
   {
      toApply_conserveMemory = pressed;
   }
   else if ( pWidget == pWidgetCheckEnableProcessPendingEvents )
   {
      toApply_enableProcessPendingEvents = pressed;
   }
   else if ( pWidget == pWidgetCheckBuildFuncTree )
   {
      toApply_buildFuncTree = pressed;
   }
   else if ( pWidget == pWidgetCheckFuncTreeFontify )
   {
      toApply_fontifyFuncTrees = pressed;
   }
   else if ( pWidget == pWidgetCheckFuncTreeVerbose )
   {
      toApply_funcTreeVerbose = pressed;
   }
   else if ( pWidget == pWidgetCheckKnrStyle )
   {
      toApply_knrStyle = pressed;
   }
   else if ( pWidget == pWidgetCheckAutoSelectNotebookPage )
   {
      toApply_autoSelectNotebookPage = pressed;
   }
   else if ( pWidget == pWidgetRadioAuxKeyLeftCtrl )
   {
      if ( pressed) toApply_auxKey = GDK_Control_L;
   }
   else if ( pWidget == pWidgetRadioAuxKeyLeftShift )
   {
      if ( pressed) toApply_auxKey = GDK_Shift_L;
   }
   else if ( pWidget == pWidgetRadioTreeKeyLeftCtrl )
   {
      if ( pressed ) toApply_treeKey = GDK_Control_L;
   }
   else if ( pWidget == pWidgetRadioTreeKeyLeftShift )
   {
      if ( pressed ) toApply_treeKey = GDK_Shift_L;
   }
   else if ( pWidget == pWidgetRadioTreeKeyLeftAlt )
   {
      if ( pressed ) toApply_treeKey = GDK_Alt_L;
   }
   else if ( pWidget == pWidgetRadioSearchDefaultNormal )
   {
      toApply_searchDefault = pressed ? SEARCH_NORMAL : SEARCH_REGEX;
   }
   else if ( pWidget == pWidgetRadioRegexScopeLine )
   {
      toApply_regexScope = pressed ? REGEX_SCOPE_LINE : REGEX_SCOPE_SPAN;
   }
   // for Editor
   else if ( pWidget == pWidgetCheckHilite )
   {
        /*
         * Apply button for highlighting.
         */
         if ( pressed ) //RedrawBothTextWidgets();
         {
            hilite = pressed;
            GtkTextBuffer * pSrcBuf=NULL;
            pSrcBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pWidgetTextMain));
            SetBufferHighlight(GTK_SOURCE_BUFFER(pSrcBuf), ActiveModuleName() );
            //gtk_source_buffer_set_highlight(GTK_SOURCE_BUFFER(pSrcBuf),hilite);
            pSrcBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pWidgetTextAux));
            SetBufferHighlight(GTK_SOURCE_BUFFER(pSrcBuf), ActiveModuleName() );
            //gtk_source_buffer_set_highlight(GTK_SOURCE_BUFFER(pSrcBuf),hilite);
         }
         else
            hilite = pressed;

   }
   else if ( pWidget == pWidgetCheckCurrentLineHighlight )
   {
       gtk_source_view_set_highlight_current_line(
                                      GTK_SOURCE_VIEW(pWidgetTextMain),
                                      pressed);
       gtk_source_view_set_highlight_current_line(
                                      GTK_SOURCE_VIEW(pWidgetTextAux),
                                      pressed);
   }
   else if ( pWidget == pWidgetCheckSpaceInsteadTab )
   {
       gtk_source_view_set_insert_spaces_instead_of_tabs(
                                      GTK_SOURCE_VIEW(pWidgetTextMain),
                                      pressed);
       gtk_source_view_set_insert_spaces_instead_of_tabs(
                                      GTK_SOURCE_VIEW(pWidgetTextAux),
                                      pressed);
   }
   else if ( pWidget == pWidgetCheckLineNumber )
   {
       gtk_source_view_set_show_line_numbers(
                                      GTK_SOURCE_VIEW(pWidgetTextMain),
                                      pressed);
       gtk_source_view_set_show_line_numbers(
                                      GTK_SOURCE_VIEW(pWidgetTextAux),
                                      pressed);
   }
   else if ( pWidget == pWidgetCheckSmartHOME_END )
   {
       gtk_source_view_set_smart_home_end(
                                      GTK_SOURCE_VIEW(pWidgetTextMain),
                                      pressed);
       gtk_source_view_set_smart_home_end(
                                      GTK_SOURCE_VIEW(pWidgetTextAux),
                                      pressed);
   }
   else if ( pWidget == pWidgetCheckAutoIndent )
   {
       gtk_source_view_set_auto_indent(
                                      GTK_SOURCE_VIEW(pWidgetTextMain),
                                      pressed);
       gtk_source_view_set_auto_indent(
                                      GTK_SOURCE_VIEW(pWidgetTextAux),
                                      pressed);
   }
   else if ( pWidget == pWidgetCheckRightMargin )
   {
       gtk_source_view_set_show_right_margin(
                                      GTK_SOURCE_VIEW(pWidgetTextMain),
                                      pressed);
       gtk_source_view_set_show_right_margin(
                                      GTK_SOURCE_VIEW(pWidgetTextAux),
                                      pressed);
   }
   // end for Editor
   else /* --none of the above-- */
      WarningMalfunction();

   gnome_property_box_changed( GNOME_PROPERTY_BOX(pWidgetPropertyBox) );
   return;
}

void
HandlerPropertyPageClicked(GtkWidget* pWidget,
                       gint page,
                       gpointer pUnused)
{
    SaveVars();
    PrintStatusbar( _("Preferences saved as ~/.gnome2/hypersrc" ));
    return ;
}
/*****************************************************************************
 * Handler for when Apply is clicked in property page box.
 *****************************************************************************/
void
HandlerPropertyPageApply( GtkWidget* pWidget,
                          gint       page,
                          gpointer   pUnused )
{
   int			tmp;
   static int	cnt = 0;
   gboolean		needToRefreshTrees = FALSE;

  /*
   * Don't re-enter.
   */
   if ( busy_PropertyPageApply )
      return;
   busy_PropertyPageApply = TRUE;

g_return_if_fail( cnt++ < 100 ); /* in case resolving a key conflict causes a loop */

  /*
   * Commit pending changes to vars now that Apply was clicked.
   */
   switch ( page )
   {
      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case PROPERTY_PAGE_FONTS:

         break; /* N/A */

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case PROPERTY_PAGE_LAYOUT:
        /*
         * There is no paned nor box functions to support swapping
         * the list and text widgets, so a change to "textLeft"
         * will have to take effect when the program is run again.
         */
         toolbarPlacement   = toApply_toolbarPlacement;
         textLeft			= toApply_textLeft;
         dialogPlacement	= toApply_dialogPlacement;
         break;

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case PROPERTY_PAGE_NUMBERS:
         /* tab width */
         tabWidth = atoi( gtk_entry_get_text( GTK_ENTRY(pWidgetEntryTabWidth) ) );
         ApplyTabWidth( pWidgetTextMain, tabWidth );
         if ( pWidgetTextAux ) ApplyTabWidth( pWidgetTextAux, tabWidth );

         /* maximum tags */
         maxTags = atoi( gtk_entry_get_text( GTK_ENTRY(pWidgetEntryMaxTags) ) );

         /* mouse wheel */
         mouseWheelNormal = (float)atof( gtk_entry_get_text( GTK_ENTRY(pWidgetEntryMouseWheelNormal) ) );
         mouseWheelFast   = (float)atof( gtk_entry_get_text( GTK_ENTRY(pWidgetEntryMouseWheelFast) ) );

         RedrawBothTextWidgets();

         break;
      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case PROPERTY_PAGE_EDITOR:
         // do nothing
         break;
      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case PROPERTY_PAGE_MISC:

        /*
         * Apply button for line column.
         */
         if ( showLineColumn != toApply_showLineColumn )
         {
            showLineColumn = toApply_showLineColumn;
            gtk_clist_set_column_visibility( GTK_CLIST(pWidgetClistTags), tagsLineColumn, showLineColumn );
            if ( pWidgetClistHistory )
            gtk_clist_set_column_visibility( GTK_CLIST(pWidgetClistHistory), tagsLineColumn, showLineColumn );
         }

        /*
         * Apply button for conserving memory.
         */
         conserveMemory = toApply_conserveMemory;
         speed = !conserveMemory;

        /*
         * Apply button for enabling ProcessPendingEvents().
         */
         enableProcessPendingEvents = toApply_enableProcessPendingEvents;

        /*
         * Apply button for enabling building functree.
         * !!! The effect is deferred, therefore, don't change skipFuncTree !!!
         */
         skipFuncTree_pref = ! toApply_buildFuncTree;

        /*
         * Apply button for using bold/italic fonts in module/func trees.
         */
         if ( fontifyFuncTrees != toApply_fontifyFuncTrees )
         {
            needToRefreshTrees = TRUE;
            fontifyFuncTrees = toApply_fontifyFuncTrees;
            if ( fontifyFuncTrees )
               SelectDifferentFontsForFuncTrees( fontNameTree );
            else
               SelectSameFontForFuncTrees( fontNameTree );
         }

        /*
         * Apply button for verbose functree.
         */
         if ( funcTreeVerbose != toApply_funcTreeVerbose )
         {
            needToRefreshTrees = TRUE;
            funcTreeVerbose = toApply_funcTreeVerbose;
         }

        /*
         * Apply button to parse K&R style functions.
         */
         if ( knrStyle != toApply_knrStyle )
         {
            knrStyle = toApply_knrStyle;
         }

        /*
         * Apply button for automatically selecting notebook pages.
         */
         autoSelectNotebookPage = toApply_autoSelectNotebookPage;

        /*
         * Refresh the module/func trees if necessary.
         */
         if ( needToRefreshTrees )
         {
            RefreshModuleTree();
            RefreshFuncTree();
         }

         break;

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case PROPERTY_PAGE_KEYBOARD:
        /*
         * Apply keyboard settings for aux text widget.
         */
         if ( toApply_auxKey == GDK_Control_L )
         {
            auxKeyGdkKeyval = GDK_Control_L;
            auxKeyGdkMask   = GDK_CONTROL_MASK;
         }
         else if ( toApply_auxKey == GDK_Shift_L )
         {
            auxKeyGdkKeyval = GDK_Shift_L;
            auxKeyGdkMask   = GDK_SHIFT_MASK;
         }

        /*
         * Apply keyboard settings for tree updating.
         */
         if ( toApply_treeKey == GDK_Control_L )
         {
            treeKeyGdkKeyval = GDK_Control_L;
            treeKeyGdkMask   = GDK_CONTROL_MASK;
         }
         else if ( toApply_treeKey == GDK_Shift_L )
         {
            treeKeyGdkKeyval = GDK_Shift_L;
            treeKeyGdkMask   = GDK_SHIFT_MASK;
         }
         else if ( toApply_treeKey == GDK_Alt_L )
         {
            treeKeyGdkKeyval = GDK_Alt_L;
            treeKeyGdkMask   = GDK_MOD1_MASK;
         }

        /*
         * If the user inadvertently selected a key that is selected
         * in another radio set, then automatically select another key.
         */
         if ( auxKeyGdkKeyval == treeKeyGdkKeyval )
         {
            if ( toApply_auxKey != -1 ) /* if aux key pref (and possibly tree key also) was changed */
            {
               if ( treeKeyGdkKeyval == GDK_Control_L ) /* Left-Ctrl was selected twice */
               {
                  treeKeyGdkKeyval = GDK_Shift_L;       /* select Left-Shift instead */
                  treeKeyGdkMask   = GDK_SHIFT_MASK;
                  gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioTreeKeyLeftShift), TRUE );
               }
               else if ( treeKeyGdkKeyval == GDK_Shift_L ) /* Left-Shift was selected twice */
               {
                  treeKeyGdkKeyval = GDK_Control_L;        /* select Left-Ctrl instead */
                  treeKeyGdkMask   = GDK_CONTROL_MASK;
                  gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioTreeKeyLeftCtrl),  TRUE );
               }
            }
            else /* if tree key pref was changed */
            {
               if ( auxKeyGdkKeyval == GDK_Control_L ) /* Left-Ctrl was selected twice */
               {
                  auxKeyGdkKeyval = GDK_Shift_L;       /* select Left-Shift instead */
                  auxKeyGdkMask   = GDK_SHIFT_MASK;
                  gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioAuxKeyLeftShift), TRUE );
               }
               else if ( auxKeyGdkKeyval == GDK_Shift_L ) /* Left-Shift was selected twice */
               {
                  auxKeyGdkKeyval = GDK_Control_L;        /* select Left-Ctrl instead */
                  auxKeyGdkMask   = GDK_CONTROL_MASK;
                  gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(pWidgetRadioAuxKeyLeftCtrl),  TRUE );
               }
            }
         }

         toApply_auxKey  = -1; /* don't re-apply */
         toApply_treeKey = -1; /* don't re-apply */
         break;

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case PROPERTY_PAGE_SEARCH:
         searchDefault		= toApply_searchDefault;
         regexScope			= toApply_regexScope;
         break;

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      case -1: /* GNOME sends -1 to indicate end of broadcast */
         break;

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      default:
         busy_PropertyPageApply = FALSE;
         g_return_if_fail(0);
   }
   SaveVars();
   PrintStatusbar( _("Preferences saved as ~/.gnome2/hypersrc" ));
   busy_PropertyPageApply = FALSE;
}

/*****************************************************************************
 * Handler for when Close is clicked in property page box.
 *****************************************************************************/
gint
HandlerPropertyPageClose( GnomeDialog* pGnomeDialog,
                          gpointer     pUnused )
{
  /*
   * Don't assign NULL if the apply operation hasn't finished yet,
   * otherwise it would cause SIGSEGV.
   */
   if( busy_PropertyPageApply ) return TRUE;

   pWidgetPropertyBox = NULL;
   return FALSE;
}

/*****************************************************************************
 * Save font names.
 * @param   fontName* (GLOBAL) --> fontName*Copy (GLOBAL)
 *****************************************************************************/
void
SaveFontNames( void )
{
   strncpy( fontNameTextCopy,			fontNameText,			MAX_FONT_NAME_LEN );
   strncpy( fontNameTreeCopy,			fontNameTree,			MAX_FONT_NAME_LEN );
   strncpy( fontNameListCopy,			fontNameList,			MAX_FONT_NAME_LEN );
/*
   strncpy( fontNameHiliteCommentCopy,	fontNameHiliteComment,	MAX_FONT_NAME_LEN );
   strncpy( fontNameHiliteKeywordCopy,	fontNameHiliteKeyword,	MAX_FONT_NAME_LEN );
   strncpy( fontNameHiliteTypeCopy,		fontNameHiliteType,		MAX_FONT_NAME_LEN );
   strncpy( fontNameHiliteSymbolCopy,	fontNameHiliteSymbol,	MAX_FONT_NAME_LEN );
 */
}

/*****************************************************************************
 * Restore font names.
 * @param   fontNameCopy* (GLOBAL) --> fontName* (GLOBAL)
 *****************************************************************************/
void
RestoreFontNames( void )
{
   strncpy( fontNameText,			fontNameTextCopy,			MAX_FONT_NAME_LEN );
   strncpy( fontNameList,			fontNameListCopy,			MAX_FONT_NAME_LEN );
   strncpy( fontNameTree,			fontNameTreeCopy,			MAX_FONT_NAME_LEN );
/*
   strncpy( fontNameHiliteComment,	fontNameHiliteCommentCopy,	MAX_FONT_NAME_LEN );
   strncpy( fontNameHiliteKeyword,	fontNameHiliteKeywordCopy,	MAX_FONT_NAME_LEN );
   strncpy( fontNameHiliteType,		fontNameHiliteTypeCopy,		MAX_FONT_NAME_LEN );
   strncpy( fontNameHiliteSymbol,	fontNameHiliteSymbolCopy,	MAX_FONT_NAME_LEN );
 */
}

/*****************************************************************************
 * Apply fonts.  To be called when font names are changed.
 * @return Zero if every font was successfully applied.
 *****************************************************************************/
int
ApplyFonts( gboolean applyTreeFont )
{
   int	error = 0;

   ApplyFontListWidgets();								/* apply list fonts */
   ChangeStyleFont( pWidgetTextMain, fontNameText );	/* apply text font */
   if ( pWidgetTextAux )
      ChangeStyleFont( pWidgetTextAux,  fontNameText );
   RedrawBothTextWidgets();								/* apply hilite fonts */

  /*
   * Applying tree fonts is done only when necessary because
   * doing so can be slow and can waste lots of memory.
   */
   if ( applyTreeFont == DO_APPLY_TREE_FONTS )
   {
   /*
      if ( fontifyFuncTrees )
         error = !SelectDifferentFontsForFuncTrees( fontNameTree );
      else
         SelectSameFontForFuncTrees( fontNameTree );
      RefreshModuleTree();
      RefreshFuncTree();
   */
       ChangeStyleFont(pWidgetModuleTree, fontNameTree);
       ChangeStyleFont(pWidgetFuncTreeRoot, fontNameTree);
   }

   return error;
}
